class Animals {
    public int age;
    public String name;

    public Animals() {
        //eat();   //一般不建议这么写，当在父类的构造方法当中调用父类和子类重写的方法的时候，会限执行子类的，这样的一个缺点是，子类的变量还没有初始化
    }

    public void eat() {
        System.out.println(name+" 在吃饭");
    }
}
class Dog extends Animals {
    public String bark;
    public int age=1;
    public void eat() {
        System.out.println(name+" 在吃狗粮");
    }
}
class Bird extends Animals {
    public String color;
    @Override  //这个注解的意思是当前的代码是被重写的
    public void eat() {
        System.out.println(name+" 在吃鸟粮");
    }
}
abstract class Shape {   //抽象类，存在的意义就是被继承 ，抽象类不能被实例化
    public abstract void draw();  //可以有抽象方法，也可以不要和普通类一样，但是必须要有方法体，抽象方法不能有方法体
}
class Rect extends Shape {
    public void draw() {
        System.out.println("画矩形");  //继承了抽象方法，抽象类一定要被重写  如果子类没有重写，子类被abstract修饰即可
    }
}
class Cicle extends Shape {
    public void draw() {
        System.out.println("画圆形");
    }
}


public class JavaPolymorphism {
    public static void func(Animals animals) {
        animals.eat();
    }
    public static Animals func1() {
        return new Dog();
    }
    public static void drawMap(Shape shape) {
        shape.draw();
    }
    //多态：当父类对象引用的对象不一样的时候，表现的行为是不一样的
    public static void main1(String[] args) {
        Animals animals=new Dog(); //父类引用指向子类的对象（做到参数的统一化）
        animals.name="yuan";
        Dog dog=new Dog();
        func(dog);
        animals.name="hha";
        animals.eat();

        Dog dog1=(Dog) animals;   //向下转型
    }

    public static void main(String[] args) {
        Shape shape=new Rect();
        drawMap(shape);
        Shape shape1=new Cicle();
        drawMap(shape1);
    }
}
